package com.ts.framework.exception;

import com.google.common.collect.ImmutableMap;
import com.ts.framework.model.response.CommonCode;
import com.ts.framework.model.response.ResponseResult;
import com.ts.framework.model.response.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
@Slf4j
public class ExceptionCatch {

      //使用EXCEPTIONS存放异常类型和错误代码的映射，ImmutableMap的特点的一旦创建不可改变，并且线程安全
      private static ImmutableMap<Class<? extends Throwable>, ResultCode> EXCEPTIONS;
      //使用builder来构建一个异常类型和错误代码的异常
      protected static ImmutableMap.Builder<Class<? extends Throwable>, ResultCode> builder =
                  ImmutableMap.builder();

      static {
            //在这里加入一些基础的异常类型判断
            builder.put(HttpMessageNotReadableException.class, CommonCode.INIT_PARAM);
            builder.put(NullPointerException.class, CommonCode.INIT_PARAM);
      }

      @ExceptionHandler(CustomException.class)
      @ResponseBody
      public ResponseResult customException(CustomException customException) {
            ResultCode resultCode = customException.getResultCode();
            ResponseResult responseResult = new ResponseResult(resultCode);
            log.error("catch   exception   :   {}\r\nexception:   ", customException.getMessage());
            return responseResult;
      }

      @ExceptionHandler(Exception.class)
      @ResponseBody
      public ResponseResult exception(Exception exception) {
            //记录日志
            log.error("catch   exception:{}", exception.getMessage());
            if (EXCEPTIONS == null){
                  EXCEPTIONS = builder.build();
            }

            final ResultCode resultCode = EXCEPTIONS.get(exception.getClass());
            final ResponseResult responseResult;
            if (resultCode != null) {
                  responseResult = new ResponseResult(resultCode);
            } else {
                  responseResult = new ResponseResult(CommonCode.SERVER_ERROR);
            }
            return responseResult;

         /*   ResponseResult responseResult = new ResponseResult(CommonCode.SERVER_ERROR);
            return responseResult;*/
      }
}
